#include <semaphore.h>
#include<iostream>
#include<pthread.h>
#include<unistd.h>
#include<vector>
using namespace std;

const int default_cap = 5;

template<class T>
class RingQueue
{
public:
  RingQueue(int cap = default_cap)
  {
    sem_init(&blank_sem,0,default_cap);
    sem_init(&data_sem,0,0);
    pthread_mutex_init(&c_mtx,nullptr);
    pthread_mutex_init(&p_mtx,nullptr);
    _ringqueue.resize(cap,T());
  }
  ~RingQueue()
  {
    sem_destroy(&blank_sem);
    sem_destroy(&data_sem);
    pthread_mutex_destroy(&c_mtx);
    pthread_mutex_destroy(&p_mtx);
  }
  //生产者关注空位置
  void push(T task)
  {
    sem_wait(&blank_sem); 
    pthread_mutex_lock(&p_mtx);
    _ringqueue[p_pos++] = task;
    p_pos %= _ringqueue.size();
    pthread_mutex_unlock(&p_mtx);
    sem_post(&data_sem);
  }
  void pop(T* task)
  {
    sem_wait(&data_sem); 
    // pthread_mutex_lock(&c_mtx);
    *task = _ringqueue[c_pos++];
    c_pos %= _ringqueue.size();
    // pthread_mutex_unlock(&c_mtx);
    sem_post(&blank_sem);
  }
private:
  vector<T> _ringqueue;
  size_t c_pos = 0;
  size_t p_pos = 0;
  pthread_mutex_t c_mtx;
  pthread_mutex_t p_mtx;
  sem_t data_sem; //数据资源的数量
  sem_t blank_sem;//空位置的资源数
  int _cap;
};
